package com.settlement.system.model.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.settlement.system.common.base.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * 标准订单
 * </p>
 *
 * @author huangrensen
 * @since 2023-09-20
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SysOrder extends BaseEntity {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id")
    private String id;

    /**
     * 关联单号
     */
    private String linkNo;

    /**
     * OMS单号
     */
    private String omsNo;

    /**
     * 发退货时间
     */
    private LocalDateTime sendReturnTime;

    /**
     * 下单时间
     */
    private LocalDateTime orderTime;

    /**
     * 电商平台店铺编码
     */
    private String platformStoreCode;

    /**
     * 电商平台店铺名称
     */
    private String platformStoreName;

    /**
     * 对账系统店铺编码
     */
    private String billStoreCode;

    /**
     * 自有平台主订单号
     */
    private String onwerPreformNo;

    /**
     * 原始主订单号
     */
    private String sourcePreformMainNo;

    /**
     * 原始子订单号
     */
    private String sourcePreformSubNo;

    /**
     * PO单号
     */
    private String poNo;

    /**
     * 内部系统电商平台编码
     */
    private String innerShopCode;

    /**
     * 内部系统电商平台名称
     */
    private String innerShopName;

    /**
     * 内部系统店铺编码
     */
    private String shopCode;

    /**
     * 内部系统店铺名称
     */
    private String shopName;

    /**
     * 财务系统店铺编码
     */
    private String billSysStore;

    /**
     * 财务系统店铺名称
     */
    private String billSysStoreName;

    /**
     * 商品单价
     */
    private BigDecimal price = BigDecimal.ZERO;

    /**
     * 发货数量
     */
    private Integer qty = 0;

    /**
     * 发货金额
     */
    private BigDecimal sendAmount = BigDecimal.ZERO;

    /**
     * 退货数量
     */
    private Integer returnQty = 0;

    /**
     * 退货金额
     */
    private BigDecimal returnAmount = BigDecimal.ZERO;

    /**
     * 自系统调账日期
     */
    private LocalDateTime systemReconciliationDate;

    /**
     * 自系统调账数量
     */
    private Integer systemReconciliationQty = 0;

    /**
     * 自系统调账金额
     */
    private BigDecimal systemReconciliationAmount = BigDecimal.ZERO;

    /**
     * 所属平台
     */
    private String platform;
    /**
     * 订单状态
     */
    private String orderStatus;
    /**
     * 归档ID
     */
    private String fileAuditId;


    /**
     * 业务日期
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime businessDate;

    public boolean isAllZero(){
        // 商品单价=0，发货数量=0，发货金额=0，退货数量=0，退货金额=0
        return compareBigDecimal(price, BigDecimal.ZERO) && Objects.equals(qty, 0) && compareBigDecimal(sendAmount, BigDecimal.ZERO) && Objects.equals(returnQty, 0) && compareBigDecimal(returnAmount, BigDecimal.ZERO);
    }

    /**
     * 店铺ID
     */
    private Long storeId;

    @TableField(exist = false)
    private String tableName;

    public static boolean isDate(String field){
        return "billMonth,sendReturnTime,orderTime,systemReconciliationDate,businessDate".contains(field);
    }
    public static boolean isDecimal(String field){
        return "price,sendAmount,returnAmount,systemReconciliationAmount".contains(field);
    }

    public static Map<String, String> getColumnMap() {
        Map<String, String> columnMap = new HashMap<>();
        columnMap.put("关联单号", "linkNo");
        columnMap.put("业务日期", "businessDate");
        columnMap.put("发退货时间", "sendReturnTime");
        columnMap.put("下单时间", "orderTime");
        columnMap.put("自有平台主订单号", "onwerPreformNo");
        columnMap.put("原始主订单号", "sourcePreformMainNo");
        columnMap.put("原始子订单号", "sourcePreformSubNo");
        columnMap.put("PO单号", "poNo");
        columnMap.put("商品单价", "price");
        columnMap.put("发货数量", "qty");
        columnMap.put("发货金额", "sendAmount");
        columnMap.put("退货数量", "returnQty");
        columnMap.put("退货金额", "returnAmount");
        return columnMap;
    }

    private static boolean compareDate(LocalDateTime date1, LocalDateTime date2) {
        if (date1 == null && date2 == null) {
            return true;
        }
        if (date1 != null && date2 == null) {
            return false;
        }
        return date1 != null && date1.equals(date2);
    }

    private static boolean compareBigDecimal(BigDecimal value1, BigDecimal value2) {
        if (value1 == null && value2 == null) {
            return true;
        }
        if (Objects.isNull(value2)) {
            value2 = BigDecimal.ZERO;
        }
        return value1 != null && value1.compareTo(value2) == 0;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        SysOrder sysOrder = (SysOrder) o;
        return Objects.equals(linkNo, sysOrder.linkNo) && Objects.equals(omsNo, sysOrder.omsNo) && compareDate(sendReturnTime, sysOrder.sendReturnTime) && compareDate(orderTime, sysOrder.orderTime) && Objects.equals(onwerPreformNo, sysOrder.onwerPreformNo) && Objects.equals(sourcePreformMainNo, sysOrder.sourcePreformMainNo) && Objects.equals(sourcePreformSubNo, sysOrder.sourcePreformSubNo) && Objects.equals(poNo, sysOrder.poNo) && compareBigDecimal(price, sysOrder.price) && Objects.equals(qty, sysOrder.qty) && sendAmount.compareTo(sysOrder.sendAmount) == 0 && Objects.equals(returnQty, sysOrder.returnQty) && returnAmount.compareTo(sysOrder.returnAmount) == 0 && compareDate(systemReconciliationDate, sysOrder.systemReconciliationDate) && Objects.equals(systemReconciliationQty, sysOrder.systemReconciliationQty) && systemReconciliationAmount.compareTo(sysOrder.systemReconciliationAmount) == 0 && Objects.equals(platform, sysOrder.platform) && Objects.equals(storeId, sysOrder.storeId);
    }

    @Override
    public int hashCode() {
        return Objects.hash(linkNo, omsNo, sendReturnTime, orderTime, onwerPreformNo, sourcePreformMainNo, sourcePreformSubNo, poNo, price, qty, sendAmount, returnQty, returnAmount, systemReconciliationDate, systemReconciliationQty, systemReconciliationAmount, platform, storeId);
    }
}
